package com.pt25.service.sys.domain.config.service.impl;


import com.pt25.base.dep.db.DbConstants;
import com.pt25.base.exception.BizException;
import com.pt25.base.util.JsonUtil;
import com.pt25.base.util.PageUtil;
import com.pt25.service.sys.domain.config.constants.ConfigConstant;
import com.pt25.service.sys.domain.config.ddo.ConfigData;
import com.pt25.service.sys.domain.config.ddo.ConfigType;
import com.pt25.service.sys.domain.config.service.ConfigDataService;
import com.pt25.service.sys.repository.mysql.persistence.ConfigDataRepo;
import com.pt25.service.sys.repository.mysql.po.ConfigDataPo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.Set;

@Slf4j
@Service
public class ConfigDataServiceImpl implements ConfigDataService {
    @Resource
    private ConfigDataRepo configDataRepo;

    /**
     * redis缓存类型
     */
    private final static Set<String> dataTypeSet = new HashSet<>() {{
        add(ConfigConstant.STR);
        add(ConfigConstant.HASH);
    }};

    /**
     * 配置数据类型
     */
    private final static Set<String> coTypeSet = new HashSet<>() {{
        add(ConfigConstant.OBJ);
        add(ConfigConstant.STR);
        add(ConfigConstant.NUM);
    }};

    /**
     * 配置集合类型（OBJ单个对象集合）
     */
    private final static Set<String> valueTypeSet = new HashSet<>() {{
        add(ConfigConstant.OBJ);
        add(ConfigConstant.LIST);
        add(ConfigConstant.SET);
    }};

    @Override
    public Long addConfigData(ConfigData configData, ConfigType configType) {
        if (checkConfigData(configData, configType)) {
            ConfigDataPo configDataPo = configData.toConfigDataPo();
            configDataRepo.save(configDataPo);
            return configDataPo.getId();
        }
        return 0L;
    }

    @Override
    public Boolean delConfigData(Long id) {
        if (getConfigData(id) == null) {
            ConfigData configData = ConfigData.builder().id(id).delFlag(DbConstants.DEL_FLAG1).build();
            return configDataRepo.updateById(configData.toConfigDataPo());
        }
        return false;
    }

    @Override
    public Boolean updateConfigData(ConfigData configData, ConfigType configType) {
        if (checkConfigData(configData, configType)) {
            return configDataRepo.updateById(configData.toConfigDataPo());
        }
        return false;
    }

    @Override
    public ConfigData getConfigData(Long id) {
        ConfigDataPo configDataPo = configDataRepo.getById(id);
        if (configDataPo != null && DbConstants.DEL_FLAG0.equals(configDataPo.getDelFlag())) {
            return ConfigData.toConfigData(configDataPo);
        }
        return null;
    }

    @Override
    public PageUtil.PageVo pageConfigData(ConfigData configData) {
        return configDataRepo.pageConfigData(configData);
    }

    @Override
    public Long getConfigDataCount(Long configTypeId) {
        return configDataRepo.getConfigDataCount(configTypeId);
    }


    private boolean checkConfigData(ConfigData configData, ConfigType configType) {
        if (!dataTypeSet.contains(configData.getDataType())) {
            log.warn("dataType的值不在'[str,hash]中',configData={}！", JsonUtil.toJson(configData));
            throw new BizException("dataType的值不在[str,hash]中！");
        }
        String[] valueTypes = configData.getValueType().split("#");
        if (!coTypeSet.contains(valueTypes[0]) || !valueTypeSet.contains(valueTypes[1])) {
            log.warn("valueType数据异常,configData={}！", JsonUtil.toJson(configData));
            throw new BizException("valueType数据异常！");
        }
        if (null == configType) {
            log.warn("configTypeId数据异常,configData={}！", JsonUtil.toJson(configData));
            throw new BizException("configTypeId数据异常！");
        }
        if (!configData.getDataKey().startsWith(configType.getTypeName() + "&")) {
            log.warn("dataKey必须以\"{}&\"开头,configData={}！", configType.getTypeName(), JsonUtil.toJson(configData));
            throw new BizException("dataKey格式不对！");
        }
        ConfigDataPo configDataPoByDataKey = configDataRepo.getConfigDataPoByDataKey(configData.getDataKey());
        if (null != configDataPoByDataKey && !configDataPoByDataKey.getId().equals(configData.getId())) {
            log.warn("dataKey已经存在,configData={}！", JsonUtil.toJson(configData));
            throw new BizException("dataKey已经存在！");
        }
        return true;
    }
}
